﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Activation;
using System.ServiceModel.Web;
using System.Text;

using RajonTest.Poco;
using Rajon;

namespace RajonTest {

    [ServiceContract]
    [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
    [ServiceBehavior(InstanceContextMode = InstanceContextMode.PerSession)]
    public class OrderService {

        #region MOCK

        static List<Order> orders = new List<Order>();

        private List<Order> Orders {
            get {
                if (orders.Count == 0) {
                    Order o1 = new Order() { ClientName="ACME", DeliveryDate=new DateTime(2010, 1, 22), OrderNumber = 1 };                    
                    o1.Items = new List<OrderItem>();
                    o1.Items.Add(new OrderItem() { ItemNumber=1, ItemPrice = 12.5, OrderNumber = 1, Product = "product A", Quantity = 5 });
                    o1.Items.Add(new OrderItem() { ItemNumber = 2, ItemPrice = 8, OrderNumber = 1, Product = "product B", Quantity = 2 });
                    orders.Add(o1);
                    Order o2 = new Order() { ClientName = "ACME", DeliveryDate = new DateTime(2010, 5, 11), OrderNumber = 2 };
                    o2.Items = new List<OrderItem>();
                    o2.Items.Add(new OrderItem() { ItemNumber = 1, ItemPrice = 53, OrderNumber = 2, Product = "product C", Quantity = 3 });
                    orders.Add(o2);

                    for (int i = 0; i <= 26; i++) {
                        Order o = new Order() { ClientName = "ACME", DeliveryDate = new DateTime(2010, 5, 11), OrderNumber = i+3 };                        
                        orders.Add(o);
                    }
                }
                return orders;
            }
        }

        static List<BusinessUnit> units = new List<BusinessUnit>();

        private List<BusinessUnit> Units {
            get {
                if (units.Count != 0)
                    return units;

                // create mocks
                for (int i = 0; i < 80; i++) {
                    
                    BusinessUnit unit = new BusinessUnit();
                    unit.UnitId = Guid.NewGuid().ToString();
                    unit.UnitName = "Unit " + i;
                    units.Add(unit);

                    for (int i2 = 0; i2 < 7; i2++) {

                        BusinessUnit unit2 = new BusinessUnit();
                        unit2.UnitId = Guid.NewGuid().ToString();
                        unit2.UnitName = "Unit child " + i2;
                        unit2.UnitParentId = unit.UnitId;
                        units.Add(unit2);

                        for (int i3 = 0; i3 < 4; i3++) {

                            BusinessUnit unit3 = new BusinessUnit();
                            unit3.UnitId = Guid.NewGuid().ToString();
                            unit3.UnitName = "Unit child child " + i3;
                            unit3.UnitParentId = unit2.UnitId;
                            units.Add(unit3);

                        }

                    }


                }

                return units;
            }
        }

        #endregion

        [OperationContract]
        [WebGet(UriTemplate = "Orders", ResponseFormat = WebMessageFormat.Json)]        
        public List<Order> GetOrders() {
            return RajonRequest.Page(Orders).ToList();
        }

        [OperationContract]
        [WebGet(UriTemplate = "Orders/{orderNumber}", ResponseFormat = WebMessageFormat.Json)]
        public Order GetOrder(string orderNumber) {            
            return Orders.SingleOrDefault(o=>o.OrderNumber== int.Parse(orderNumber));
        }

        [OperationContract]
        [WebInvoke(Method = "PUT", UriTemplate = "Orders/{orderNumber}", ResponseFormat = WebMessageFormat.Json)]
        public void UpdateOrder(string orderNumber, Order updatedOrder) {
            Order o = GetOrder(orderNumber);
            if (o == null)
                throw new WebFaultException(System.Net.HttpStatusCode.BadRequest);
            o.ClientName = updatedOrder.ClientName;
            o.DeliveryDate = updatedOrder.DeliveryDate;
        }
        
        [OperationContract]
        [WebInvoke(Method = "POST", UriTemplate = "Orders", ResponseFormat = WebMessageFormat.Json)]
        public int CreateOrder(Order newOrder) {
            int orderNumber = Orders.Max(o => o.OrderNumber) + 1;
            newOrder.OrderNumber = orderNumber;
            Orders.Add(newOrder);
            return orderNumber;
        }

        [OperationContract]
        [WebInvoke(Method = "POST", UriTemplate = "Orders/{orderNumber}/Items", ResponseFormat = WebMessageFormat.Json)]
        public int CreateOrderItem(string orderNumber, OrderItem newItem) {
            Order o = GetOrder(orderNumber);
            if (o == null)
                throw new WebFaultException(System.Net.HttpStatusCode.BadRequest);
            int itemNumber = 1;

            if (o.Items == null)
                o.Items = new List<OrderItem>();

            if(o.Items.Count>0)                 
                itemNumber = o.Items.Max(i => i.ItemNumber) + 1;

            newItem.ItemNumber = itemNumber;

            o.Items.Add(newItem);
            return newItem.ItemNumber;
        }

        [OperationContract]
        [WebInvoke(Method = "DELETE", UriTemplate = "Orders/{orderNumber}/Items/{itemNumber}", ResponseFormat = WebMessageFormat.Json)]
        public void DeleteOrderItem(string orderNumber, string itemNumber) {
            Order o = GetOrder(orderNumber);
            if (o == null)
                throw new WebFaultException(System.Net.HttpStatusCode.BadRequest);
            
            OrderItem item = o.Items.SingleOrDefault(i=>i.ItemNumber == int.Parse(itemNumber));
            if(item==null)
                throw new WebFaultException(System.Net.HttpStatusCode.BadRequest);
            
            o.Items.Remove(item);

        }

        [OperationContract]
        [WebInvoke(Method = "POST", UriTemplate = "SignedUsers", ResponseFormat = WebMessageFormat.Json)]
        public bool SignInUser(string user) {
            System.Web.HttpContext.Current.Session["user"] = user;
            return true;
        }

        [OperationContract]
        [WebInvoke(Method = "GET", UriTemplate = "MyUser", ResponseFormat = WebMessageFormat.Json)]
        public string CurrentUser() {
            object o = System.Web.HttpContext.Current.Session["user"];
            if (o == null)
                return "";
            return o.ToString();            
        }


        [OperationContract]
        [WebGet(UriTemplate = "BusinessUnits/?unitParentId={unitParentId}", ResponseFormat = WebMessageFormat.Json)]
        public List<BusinessUnit> GetBusinessUnits(string unitParentId) {

            System.Web.HttpContext.Current.Response.Cache.SetExpires(new DateTime(2012, 1, 1));

            return Units.Where(u => u.UnitParentId==unitParentId).ToList();
        }

    }


}
